package com.ifast.common.storage;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import java.net.MalformedURLException;

import java.nio.file.Files;

import java.nio.file.Path;

import java.nio.file.Paths;

import java.nio.file.StandardCopyOption;

import java.util.stream.Stream;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.core.io.Resource;

import org.springframework.core.io.UrlResource;

import org.springframework.stereotype.Service;

import org.springframework.util.FileSystemUtils;

import org.springframework.util.StringUtils;

import org.springframework.web.multipart.MultipartFile;

import com.ifast.common.config.IFastConfig;
import com.ifast.common.storage.StorageException;
import com.ifast.common.storage.StorageFileNotFoundException;
import com.ifast.common.storage.StorageService;
import com.ifast.common.utils.FileUtil;

/**
 * 
 * 文件系统存储服务
 * 
 * @author fantasy
 *
 * 
 * 
 */

@Service
public class FileSystemStorageService implements StorageService {

	// 文件存储路径
	@Autowired
	private IFastConfig iFastConfig;

	@Override
	public String store(MultipartFile file) {
		String filename = FileUtil.renameToUUID(StringUtils.cleanPath(file.getOriginalFilename()));
		try {
			if (file.isEmpty()) {
				throw new StorageException("File is empty： " + filename);
			}
			if (filename.contains("..")) {
				// 文件路径安全校验
				throw new StorageException("不能将文件保存到相对目录路径中： " + filename);
			}
			// 将上传的文件保存到指定位置
			Files.copy(file.getInputStream(), Paths.get(iFastConfig.getUploadDir()).resolve(filename),
					StandardCopyOption.REPLACE_EXISTING);
			return filename;
		} catch (IOException e) {
			throw new StorageException("上传文件失败 " + filename, e);
		}
		/*String filename = StringUtils.cleanPath(file.getOriginalFilename());
		File targetFile = new File(filePath);  
        if(!targetFile.exists()){    
            targetFile.mkdirs();    
        }       
		try {
			FileOutputStream out = new FileOutputStream(filePath+filename);
			out.write(file.getBytes());
	        out.flush();
	        out.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        return filePath+filename;*/
	}

	/**
	 * 
	 * 加载所有的文件路径
	 * 
	 */

	@Override

	public Stream<Path> loadAll() {
		try {
			return Files.walk(Paths.get(iFastConfig.getUploadDir()), 1)
					.filter(path -> !path.equals(Paths.get(iFastConfig.getUploadDir())))
					.map(path -> Paths.get(iFastConfig.getUploadDir()).relativize(path));
		}

		catch (IOException e) {
			throw new StorageException("Failed to read stored files", e);
		}

	}

	@Override

	public Path load(String filename) {
		return Paths.get(iFastConfig.getUploadDir()).resolve(filename);

	}

	@Override

	public Resource loadAsResource(String filename) {

		try {

			Path file = load(filename);

			Resource resource = new UrlResource(file.toUri());

			if (resource.exists() || resource.isReadable()) {
				return resource;
			}

			else {
				throw new StorageFileNotFoundException("Could not read file: " + filename);
			}

		}

		catch (MalformedURLException e) {

			throw new StorageFileNotFoundException("Could not read file: " + filename, e);

		}

	}

	@Override

	public void deleteAll() {
		FileSystemUtils.deleteRecursively(Paths.get(iFastConfig.getUploadDir()).toFile());
	}

	@Override

	public void init() {
		try {
			Files.createDirectories(Paths.get(iFastConfig.getUploadDir()));
		} catch (IOException e) {
			throw new StorageException("Could not initialize storage", e);
		}

	}

}
